/**
 * Copyright 2000 self.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 *
 * @author Ashin Wimalajeewa
 */
package self.amigo.elem.uml;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

import org.w3c.dom.*;

import self.awt.*;
import self.awt.painter.*;
import self.gee.*;
import self.lang.*;
import self.xml.*;

import self.amigo.elem.*;

public class SequenceDiagramSelfMessageView extends ARectangularLinkable {
	
	/**
	 * If the internal state of this class ever changes in such a way that it can't be defaulted,
	 * then the {@link #serialVersionUID} should be incremented to ensure serialized instances cleanly fail.  
	 */
	private static final long serialVersionUID = 1;
	
	final static public Font MESSAGE_FONT = new Font( "Arial", 0, 10 );

  public SequenceDiagramSelfMessageView() {
    delegate =  new Essential();
    setDelegate( delegate );
  }

  public class Essential extends ARectangularHandledElement {
  	
	/**
	 * If the internal state of this class ever changes in such a way that it can't be defaulted,
	 * then the {@link #serialVersionUID} should be incremented to ensure serialized instances cleanly fail.  
	 */
	private static final long serialVersionUID = 1;
	
    private boolean       isAsync = false;
    private String        message = "message()";

    protected Point   pointTl = new Point();
    protected Point   pointTr = new Point();
    protected Point   pointBr = new Point();
    protected Point   pointBl = new Point();

    protected LinePainter linePainter;

    private LinePaintContext  ctxLine = new LinePaintContext();

    public Essential() {
      fig.setBounds( 10, 10, 40, 20 );
      resetFrame();
    }

    public void       setLayer( IDiagramLayer layerToDrawOn, boolean add ) {
      super.setLayer( layerToDrawOn, add );
      linePainter = (LinePainter) PainterManager.getPainterForOwner( layer, LinePainter.class );
    }

    public void paint( Graphics surface ) {
      linePainter.paint( surface, ctxLine, outlineOnly );
      if ( !outlineOnly && !StringUtils.isNullOrEmpty(message) )
        surface.drawString( message, fig.x, fig.y + fig.height + 10 );
    }

    public void       resize( int x, int y, Point[] handle, MouseEvent e, int dragState ) {
      if ( dragState == IGraphicElement.DS_AFTER_LAST ) {
        super.resize( x, y, handle, e, dragState );
        return;
      }

      layer.beginUpdate();
      super.resize( x, y, handle, e, dragState );
      if ( fig.width < 10 )
        fig.width = 10;
      if ( fig.height < 10 )
        fig.height = 10;
      resetFrame();
      layer.endUpdate();
    }

    // IEditableElement support
    public void       getProperties( Map store ) {
      store.put( CollaborationMessageView.MESSAGE_PROP, message );
      store.put( CollaborationMessageView.ASYNC_PROP, isAsync ? Boolean.TRUE: Boolean.FALSE );
    }

    public void       setProperties( Map data ) {
      message = (String) data.get( CollaborationMessageView.MESSAGE_PROP );
      isAsync = ((Boolean) data.get(CollaborationMessageView.ASYNC_PROP)).booleanValue();
      layer.setDirty();
    }

    // IPersistentElement support
    public void readFrom( Node self, HashMap idObjLookUp ) throws DOMException {
      super.readFrom( self, idObjLookUp );

      String asyncAsString = DomUtils.getElementAttribute( self, CollaborationMessageView.ASYNC_PROP );
      isAsync = BooleanUtils.toValue( asyncAsString );
      Node det = DomUtils.getChildElementNode( self, CollaborationMessageView.MESSAGE_PROP );
      message = DomUtils.getElementText( det );
      resetFrame();
    }

    public void writeTo( Document doc, Element self, HashMap objIdLookup ) throws DOMException {
      super.writeTo( doc, self, objIdLookup );

      DomUtils.setElementAttribute( self, CollaborationMessageView.ASYNC_PROP, "" + isAsync );
      Element det = doc.createElement( CollaborationMessageView.MESSAGE_PROP );
      self.appendChild( det );
      DomUtils.setElementText( det, StringUtils.toEmptyIfNull(message) );
    }

    public void resetFrame() {
      int right  = fig.x + fig.width;
      int bottom = fig.y + fig.height;
      pointTl.setLocation( fig.x, fig.y );
      pointTr.setLocation( right, fig.y );
      pointBr.setLocation( right, bottom );
      pointBl.setLocation( fig.x, bottom );
    }

    protected class LinePaintContext implements ILineRenderInfo, Serializable {
    	
    	/**
    	 * If the internal state of this class ever changes in such a way that it can't be defaulted,
    	 * then the {@link #serialVersionUID} should be incremented to ensure serialized instances cleanly fail.  
    	 */
    	private static final long serialVersionUID = 1;
    	
      private ArrayList points = new ArrayList();

      public Color getColor() {
        return frameColor;
      }

      public LinePaintContext() {
        points.add( pointTl );
        points.add( pointTr );
        points.add( pointBr );
        points.add( pointBl );
      }

      public boolean isDashed() {
        return false;
      }

      public float getWidth() {
        return 1.0f;
      }

      public java.util.List getPoints() {
        return points;
      }

      public String getLineName() {
        return null;
      }

      public String getLineHeader() {
        return null;
      }

      public int getSideAHead() {
        return ILineRenderInfo.NO_HEAD;
      }

      public String getSideAMajor() {
        return null;
      }

      public String getSideAMinor() {
        return null;
      }

      public int getSideBHead() {
        if ( isAsync )
          return ILineRenderInfo.HALF_OPEN_ARROW_HEAD;
        return ILineRenderInfo.OPEN_ARROW_HEAD;
      }

      public String getSideBMajor() {
        return null;
      }

      public String getSideBMinor() {
        return null;
      }

      public int getHeadDiameter() {
        return 12;
      }
    }
  }
}
